package han.chensing.latos.common.level.util;

public class MathUtil {

    public static float range(float min,float x,float max){
        return Math.max(min,Math.min(x,max));
    }

    public static boolean isInRange(float min, float x, float max){return min<=x&&x<=max;}

    public static int judgeRange(float min,float x,float max){
        return isInRange(min,x,max)?0:x<min?-1:x>max?1:2;
    }

    public static float[] genBezierPointMap(
            float x1,float y1,float x2,float y2,
            float x3,float y3,float x4,float y4,int length){
        float[] out=new float[length+1];
        float step = 1f / (float) length;
        int j=0;
        for (float i=0;j<length;i+=step,j++){
            out[j]=getBezierAbsolute(i,x1,y1,x2,y2,x3,y3,x4,y4,0,1,4E-4F);
        }
        out[length]=1;
        return out;
    }

    public static float getBezierIntegration(
            float x1,float y1,float x2,float y2,
            float x3,float y3,float x4,float y4){
        float step=5E-4F;
        float accuracy=4E-4F;
        float total=0;
        for(float i=0;i<x4;i+=step){
            float t=getBezierAbsolute(i,x1,y1,x2,y2,x3,y3,x4,y4,
                    0,1,accuracy)*step;
            total+=t;
        }
        return total;
    }

    public static float getBezierAbsolute(
            float t,
            float x1,float y1,float x2,float y2,
            float x3,float y3,float x4,float y4,
            float closeFrom,float closeTo,float closeD){
        float v = closeBezierX(x1, x2, x3, x4, closeFrom, closeTo, closeD, t);
        return getBezier(v,y1,y2,y3,y4);
    }

    public static float closeBezierX(
            float x1,float x2,float x3,float x4,
            float from,float to,float d,float target){
        if (target<=0)return 0;
        if (target>=1)return 1;
        float start=from,end=to;
        float nowV;
        float t;
        do {
            t=(start+end)/2f;
            nowV=getBezier(t,x1,x2,x3,x4);
            if (nowV<target)
                start=t;
            else if (nowV>target)
                end=t;
        }while (target-d>=nowV||target+d<=nowV);
        return t;
    }

    public static float getBezier(float t,float xy1,float xy2,float xy3,float xy4){
        float a = 1 - t;
        return xy1*a*a*a+3*t*xy2*a*a+3*t*t*xy3*a+t*t*t*xy4;
    }
}
